using System;
using FireStarter.Base;
using Firestarter.DB.Schema.BO;
using Firestarter.DB.Schema.Logic;
using FireStarterModeller.BO;
using Habanero.Util;

namespace Firestarter.DB_DomainModel.Logic
{
    public class DBToDMPropertyImporter : IDBToDMPropertyImporter
    {
        public IDBToDMPropertyUpdater DBToDMPropertyUpdater { get; private set; }

        private DMClass Class { get; set; }

        public DBToDMPropertyImporter(IDBToDMPropertyUpdater dbToDMPropertyUpdater)
        {
            if (dbToDMPropertyUpdater == null) throw new ArgumentNullException("dbToDMPropertyUpdater");
            DBToDMPropertyUpdater = dbToDMPropertyUpdater;
        }

        public DMProperty Import(DMClass dmClass, IDBColumn dbColumn)
        {
            if (dmClass == null) throw new ArgumentNullException("dmClass");
            if (dbColumn == null) throw new ArgumentNullException("dbColumn");
            Class = dmClass;

            DMProperty foundDMProperty = dbColumn.FindBOProperty(Class);
            if (foundDMProperty == null && !ApprovedDelete(dbColumn))
            {
                return CreateDMProperty(Class, dbColumn);
            }
            if (ApprovedDelete(dbColumn))
            {
                dbColumn.MarkForDelete();
                if (foundDMProperty != null) foundDMProperty.MarkForDelete();
                
                return foundDMProperty;
            }
            if(foundDMProperty != null)
            {
                foundDMProperty.MappedDBColumnID = dbColumn.ColumnID;
                foundDMProperty.MappedDBColumnName = dbColumn.ColumnName;
                return UpdateProperty(foundDMProperty);
            }

            return foundDMProperty;
        }

        private DMProperty CreateDMProperty(DMClass dmClass, IDBColumn dbColumn)
        {
            DMProperty newProperty = new DMProperty
                                         {
                                             MappedDBColumnID = dbColumn.ColumnID,
                                             MappedDBColumnName = dbColumn.ColumnName
                                         };
            UpdateProperty(newProperty);
            dmClass.Properties.Add(newProperty);
            return newProperty;
        }

        private bool ApprovedDelete(IMergableBo column)
        {
            return column.PendingChangeType == ChangeType.Delete && column.PendingChangeApproved;
        }
        private DMProperty UpdateProperty(DMProperty property)
        {
            IDBColumn mappedDBColumn = property.MappedDBColumn;
            DBToDMPropertyUpdater.UpdateValues(mappedDBColumn, property);
            FixPropertySameNameAsClass(property);
            return property;
        }

        private void FixPropertySameNameAsClass(DMProperty property)
        {
            if (property.PropertyType != null && property.PropertyTypeString == "System.String")
            {
                if (property.PropertyName == this.Class.ClassNameBO)
                {
                    property.PropertyName += "Name";
                }
            }
        }
    }
}